#include "AiServiceSettings.h"
#include <QSettings>
#include <QDialog>
#include <QFormLayout>
#include <QLineEdit>
#include <QDialogButtonBox>
#include <QDebug>
#include <QCoreApplication>
#include <QDir>
#include <QJsonObject>
#include <QJsonDocument>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QPushButton>
#include <QLabel>
#include <QJsonArray>
#include <QEventLoop>
#include <QCheckBox>
#include <QThread>

AIServiceSettings::AIServiceSettings(QObject *parent)
    : QObject(parent), networkManager(new QNetworkAccessManager(this))
{
    loadSettings();

    m_llamaServerManager = new LlamaServerManager(this);
}

void AIServiceSettings::loadSettings()
{
    QString settingsFilePath = QCoreApplication::applicationDirPath() + "/aiservicesettings.ini";
    QSettings settings(settingsFilePath, QSettings::IniFormat);
    chatAIUrl = settings.value("ChatAIUrl", DEFAULT_CHAT_AI_URL).toString();
    chatAIKey = settings.value("ChatAIKey", DEFAULT_CHAT_AI_KEY).toString();
    chatAIModel = settings.value("ChatAIModel", DEFAULT_CHAT_AI_MODEL).toString();
    embeddingAIUrl = settings.value("EmbeddingAIUrl", DEFAULT_EMBEDDING_AI_URL).toString();
    embeddingAIKey = settings.value("EmbeddingAIKey", DEFAULT_EMBEDDING_AI_KEY).toString();
    embeddingAIModel = settings.value("EmbeddingAIModel", DEFAULT_EMBEDDING_AI_MODEL).toString();

    useBuiltinChatAI = settings.value("UseBuiltinChatAI", DEFAULT_USE_BUILTIN_CHAT_AI).toBool();
    useBuiltinEmbeddingAI = settings.value("UseBuiltinEmbeddingAI", DEFAULT_USE_BUILTIN_EMBEDDING_AI).toBool();
    
    chatAIModelPath = settings.value("ChatAIModelPath", QCoreApplication::applicationDirPath() + DEFAULT_CHAT_AI_MODEL_PATH).toString();
    chatAIHost = settings.value("ChatAIHost", DEFAULT_CHAT_AI_HOST).toString();
    chatAIPort = settings.value("ChatAIPort", DEFAULT_CHAT_AI_PORT).toString();
    chatAITemp = settings.value("ChatAITemp", DEFAULT_CHAT_AI_TEMP).toString();
    chatAIContextSize = settings.value("ChatAIContextSize", DEFAULT_CHAT_AI_CONTEXT_SIZE).toString();
    chatAINgl = settings.value("ChatAINgl", DEFAULT_CHAT_AI_NGL).toString();
    
    embeddingAIModelPath = settings.value("EmbeddingAIModelPath", QCoreApplication::applicationDirPath() + DEFAULT_EMBEDDING_AI_MODEL_PATH).toString();
    embeddingAIHost = settings.value("EmbeddingAIHost", DEFAULT_EMBEDDING_AI_HOST).toString();
    embeddingAIPort = settings.value("EmbeddingAIPort", DEFAULT_EMBEDDING_AI_PORT).toString();
    embeddingAITemp = settings.value("EmbeddingAITemp", DEFAULT_EMBEDDING_AI_TEMP).toString();
    embeddingAIContextSize = settings.value("EmbeddingAIContextSize", DEFAULT_EMBEDDING_AI_CONTEXT_SIZE).toString();
    embeddingAINgl = settings.value("EmbeddingAINgl", DEFAULT_EMBEDDING_AI_NGL).toString();
}

void AIServiceSettings::saveSettings()
{
    QString settingsFilePath = QCoreApplication::applicationDirPath() + "/aiservicesettings.ini";
    QSettings settings(settingsFilePath, QSettings::IniFormat);
    settings.setValue("ChatAIUrl", chatAIUrl);
    settings.setValue("ChatAIKey", chatAIKey);
    settings.setValue("ChatAIModel", chatAIModel);
    settings.setValue("EmbeddingAIUrl", embeddingAIUrl);
    settings.setValue("EmbeddingAIKey", embeddingAIKey);
    settings.setValue("EmbeddingAIModel", embeddingAIModel);

    settings.setValue("UseBuiltinChatAI", useBuiltinChatAI);
    settings.setValue("UseBuiltinEmbeddingAI", useBuiltinEmbeddingAI);
    
    settings.setValue("ChatAIModelPath", chatAIModelPath);
    settings.setValue("ChatAIHost", chatAIHost);
    settings.setValue("ChatAIPort", chatAIPort);
    settings.setValue("ChatAITemp", chatAITemp);
    settings.setValue("ChatAIContextSize", chatAIContextSize);
    settings.setValue("ChatAINgl", chatAINgl);
    
    settings.setValue("EmbeddingAIModelPath", embeddingAIModelPath);
    settings.setValue("EmbeddingAIHost", embeddingAIHost);
    settings.setValue("EmbeddingAIPort", embeddingAIPort);
    settings.setValue("EmbeddingAITemp", embeddingAITemp);
    settings.setValue("EmbeddingAIContextSize", embeddingAIContextSize);
    settings.setValue("EmbeddingAINgl", embeddingAINgl);
}

void AIServiceSettings::openSettingsDialog()
{
    QDialog dialog;
    dialog.setWindowTitle("AI服务设置");

    QFormLayout *formLayout = new QFormLayout(&dialog);

    // 现有的输入框
    QLineEdit *chatAIUrlInput = new QLineEdit(chatAIUrl, &dialog);
    QLineEdit *chatAIKeyInput = new QLineEdit(chatAIKey, &dialog);
    QLineEdit *chatAIModelInput = new QLineEdit(chatAIModel, &dialog);
    QLineEdit *embeddingAIUrlInput = new QLineEdit(embeddingAIUrl, &dialog);
    QLineEdit *embeddingAIKeyInput = new QLineEdit(embeddingAIKey, &dialog);
    QLineEdit *embeddingAIModelInput = new QLineEdit(embeddingAIModel, &dialog);

    // 设置默认值的占位符文本
    chatAIUrlInput->setPlaceholderText(DEFAULT_CHAT_AI_URL);
    chatAIKeyInput->setPlaceholderText(DEFAULT_CHAT_AI_KEY);
    chatAIModelInput->setPlaceholderText(DEFAULT_CHAT_AI_MODEL);
    embeddingAIUrlInput->setPlaceholderText(DEFAULT_EMBEDDING_AI_URL);
    embeddingAIKeyInput->setPlaceholderText(DEFAULT_EMBEDDING_AI_KEY);
    embeddingAIModelInput->setPlaceholderText(DEFAULT_EMBEDDING_AI_MODEL);

    formLayout->addRow("Chat AI URL:", chatAIUrlInput);
    formLayout->addRow("Chat AI Key:", chatAIKeyInput);
    formLayout->addRow("Chat AI Model:", chatAIModelInput);
    formLayout->addRow("Embedding AI URL:", embeddingAIUrlInput);
    formLayout->addRow("Embedding AI Key:", embeddingAIKeyInput);
    formLayout->addRow("Embedding AI Model:", embeddingAIModelInput);

    // 添加复选框和相应的输入框
    QCheckBox *useBuiltinChatAICheckBox = new QCheckBox("使用软件自带Chat AI服务", &dialog);
    useBuiltinChatAICheckBox->setChecked(useBuiltinChatAI);
    formLayout->addRow(useBuiltinChatAICheckBox);

    useBuiltinChatAICheckBox->setVisible(false); // 不显示 llama-server目前不支持多模态模型，所以设置了也没用

    QLineEdit *chatAIModelPathInput = new QLineEdit(chatAIModelPath, &dialog);
    QLineEdit *chatAIHostInput = new QLineEdit(chatAIHost, &dialog);
    QLineEdit *chatAIPortInput = new QLineEdit(chatAIPort, &dialog);
    QLineEdit *chatAITempInput = new QLineEdit(chatAITemp, &dialog);
    QLineEdit *chatAIContextSizeInput = new QLineEdit(chatAIContextSize, &dialog);
    QLineEdit *chatAINglInput = new QLineEdit(chatAINgl, &dialog);

    // 设置占位符文本
    chatAIModelPathInput->setPlaceholderText(DEFAULT_CHAT_AI_MODEL_PATH);
    chatAIHostInput->setPlaceholderText(DEFAULT_CHAT_AI_HOST);
    chatAIPortInput->setPlaceholderText(DEFAULT_CHAT_AI_PORT);
    chatAITempInput->setPlaceholderText(DEFAULT_CHAT_AI_TEMP);
    chatAIContextSizeInput->setPlaceholderText(DEFAULT_CHAT_AI_CONTEXT_SIZE);
    chatAINglInput->setPlaceholderText(DEFAULT_CHAT_AI_NGL);

    QList<QPair<QLabel*, QLineEdit*>> chatAIInputs;
    QStringList chatAILabels = {"Model Path:", "Host:", "Port:", "Temp:", "Context Size:", "NGL:"};
    QList<QLineEdit*> chatAILineEdits = {chatAIModelPathInput, chatAIHostInput, chatAIPortInput, 
                                         chatAITempInput, chatAIContextSizeInput, chatAINglInput};

    for (int i = 0; i < chatAILabels.size(); ++i) {
        QLabel *label = new QLabel(chatAILabels[i], &dialog);
        chatAIInputs.append(qMakePair(label, chatAILineEdits[i]));
        formLayout->addRow(label, chatAILineEdits[i]);
        label->setVisible(useBuiltinChatAI);
        chatAILineEdits[i]->setVisible(useBuiltinChatAI);
    }

    QCheckBox *useBuiltinEmbeddingAICheckBox = new QCheckBox("使用软件自带Embedding AI服务", &dialog);
    useBuiltinEmbeddingAICheckBox->setChecked(useBuiltinEmbeddingAI);
    formLayout->addRow(useBuiltinEmbeddingAICheckBox);

    useBuiltinEmbeddingAICheckBox->setVisible(false); // 不显示 llama-server目前不支持多模态模型，所以设置了也没用

    QLineEdit *embeddingAIModelPathInput = new QLineEdit(embeddingAIModelPath, &dialog);
    QLineEdit *embeddingAIHostInput = new QLineEdit(embeddingAIHost, &dialog);
    QLineEdit *embeddingAIPortInput = new QLineEdit(embeddingAIPort, &dialog);
    QLineEdit *embeddingAITempInput = new QLineEdit(embeddingAITemp, &dialog);
    QLineEdit *embeddingAIContextSizeInput = new QLineEdit(embeddingAIContextSize, &dialog);
    QLineEdit *embeddingAINglInput = new QLineEdit(embeddingAINgl, &dialog);

    // 设置占位符文本
    embeddingAIModelPathInput->setPlaceholderText(QCoreApplication::applicationDirPath() + DEFAULT_EMBEDDING_AI_MODEL_PATH);
    embeddingAIHostInput->setPlaceholderText(DEFAULT_EMBEDDING_AI_HOST);
    embeddingAIPortInput->setPlaceholderText(DEFAULT_EMBEDDING_AI_PORT);
    embeddingAITempInput->setPlaceholderText(DEFAULT_EMBEDDING_AI_TEMP);
    embeddingAIContextSizeInput->setPlaceholderText(DEFAULT_EMBEDDING_AI_CONTEXT_SIZE);
    embeddingAINglInput->setPlaceholderText(DEFAULT_EMBEDDING_AI_NGL);

    QList<QPair<QLabel*, QLineEdit*>> embeddingAIInputs;
    QStringList embeddingAILabels = {"Model Path:", "Host:", "Port:", "Temp:", "Context Size:", "NGL:"};
    QList<QLineEdit*> embeddingAILineEdits = {embeddingAIModelPathInput, embeddingAIHostInput, embeddingAIPortInput, 
                                              embeddingAITempInput, embeddingAIContextSizeInput, embeddingAINglInput};

    for (int i = 0; i < embeddingAILabels.size(); ++i) {
        QLabel *label = new QLabel(embeddingAILabels[i], &dialog);
        embeddingAIInputs.append(qMakePair(label, embeddingAILineEdits[i]));
        formLayout->addRow(label, embeddingAILineEdits[i]);
        label->setVisible(useBuiltinEmbeddingAI);
        embeddingAILineEdits[i]->setVisible(useBuiltinEmbeddingAI);
    }

    // 连接复选框的 toggled 信号到 lambda 函数
    connect(useBuiltinChatAICheckBox, &QCheckBox::toggled, [chatAIInputs](bool checked) {
        for (const auto &pair : chatAIInputs) {
            pair.first->setVisible(checked);
            pair.second->setVisible(checked);
        }
    });

    connect(useBuiltinEmbeddingAICheckBox, &QCheckBox::toggled, [embeddingAIInputs](bool checked) {
        for (const auto &pair : embeddingAIInputs) {
            pair.first->setVisible(checked);
            pair.second->setVisible(checked);
        }
    });

    QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dialog);
    formLayout->addWidget(buttonBox);

    QObject::connect(buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
    QObject::connect(buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);

    // 添加测试按钮和结果显示标签
    QPushButton *testChatAIButton = new QPushButton("测试 Chat AI URL", &dialog);
    QLabel *chatAITestResult = new QLabel(&dialog);
    QPushButton *testEmbeddingAIButton = new QPushButton("测试 Embedding AI URL", &dialog);
    QLabel *embeddingAITestResult = new QLabel(&dialog);

    formLayout->addRow(testChatAIButton, chatAITestResult);
    formLayout->addRow(testEmbeddingAIButton, embeddingAITestResult);

    // 修改 Chat AI 测试按钮的连接(llama-server目前不支持多模态模型，所以设置了也没用)
    connect(testChatAIButton, &QPushButton::clicked, [this, chatAIUrlInput, chatAIKeyInput, chatAIModelInput, chatAITestResult, testChatAIButton,
            chatAIModelPathInput, chatAIHostInput, chatAIPortInput, chatAITempInput, chatAIContextSizeInput, chatAINglInput]() {
        testChatAIButton->setEnabled(false);
        chatAITestResult->setText("正在测试...");
        chatAITestResult->setStyleSheet("color: blue;");

        QString program = QCoreApplication::applicationDirPath() + "/bin/llama-server";
        QString modelPath = QCoreApplication::applicationDirPath() + chatAIModelPathInput->text();
        QString host = chatAIHostInput->text();
        QString port = chatAIPortInput->text();
        QString temp = chatAITempInput->text();
        QString contextSize = chatAIContextSizeInput->text();
        QString ngl = chatAINglInput->text();

        // m_llamaServerManager->startServer(true, program, modelPath, host, port, temp, contextSize, ngl);

        QString url = chatAIUrlInput->text().isEmpty() ? DEFAULT_CHAT_AI_URL : chatAIUrlInput->text();
        QString key = chatAIKeyInput->text().isEmpty() ? DEFAULT_CHAT_AI_KEY : chatAIKeyInput->text();
        QString model = chatAIModelInput->text().isEmpty() ? DEFAULT_CHAT_AI_MODEL : chatAIModelInput->text();
        
        QString resultMessage;
        bool success = performUrlTest(url, key, model, true, &resultMessage);
        
        chatAITestResult->setText(resultMessage);
        chatAITestResult->setStyleSheet(success ? "color: green;" : "color: red;");
        testChatAIButton->setEnabled(true);

        // m_llamaServerManager->stopServer();
    });

    // 修改 Embedding AI 测试按钮的连接
    connect(testEmbeddingAIButton, &QPushButton::clicked, [this, embeddingAIUrlInput, embeddingAIKeyInput, embeddingAIModelInput, embeddingAITestResult, testEmbeddingAIButton,
            embeddingAIModelPathInput, embeddingAIHostInput, embeddingAIPortInput, embeddingAITempInput, embeddingAIContextSizeInput, embeddingAINglInput,useBuiltinEmbeddingAICheckBox]() {
        testEmbeddingAIButton->setEnabled(false);
        embeddingAITestResult->setText("正在测试...");
        embeddingAITestResult->setStyleSheet("color: blue;");

        bool useBuiltin = useBuiltinEmbeddingAICheckBox->isChecked();

        QString url = embeddingAIUrlInput->text();
        QString key = embeddingAIKeyInput->text();
        QString model = embeddingAIModelInput->text();
        QString resultMessage;
        bool success = false;

        if (useBuiltin) {
            QString program = QCoreApplication::applicationDirPath() + "/bin/llama-server";
            QString modelPath = embeddingAIModelPathInput->text();
            QString host = embeddingAIHostInput->text();
            QString port = embeddingAIPortInput->text();
            QString temp = embeddingAITempInput->text();
            QString contextSize = embeddingAIContextSizeInput->text();
            QString ngl = embeddingAINglInput->text();

            m_llamaServerManager->startServer(false, program, modelPath, host, port, temp, contextSize, ngl);

        }

        for (int i = 0; i < 10; ++i) {
            QThread::msleep(1000);
            QCoreApplication::processEvents(); // 处理事件，保持UI响应

            success = performUrlTest(url, key, model, false, &resultMessage);
            if (success) {
                break;
            }
        }

        embeddingAITestResult->setText(resultMessage);
        embeddingAITestResult->setStyleSheet(success ? "color: green;" : "color: red;");
        testEmbeddingAIButton->setEnabled(true);

        if (useBuiltin) {
            m_llamaServerManager->stopServer();
        }
    });

    if (dialog.exec() == QDialog::Accepted) {
        // 保存设置
        chatAIUrl = chatAIUrlInput->text().isEmpty() ? DEFAULT_CHAT_AI_URL : chatAIUrlInput->text();
        chatAIKey = chatAIKeyInput->text().isEmpty() ? DEFAULT_CHAT_AI_KEY : chatAIKeyInput->text();
        chatAIModel = chatAIModelInput->text().isEmpty() ? DEFAULT_CHAT_AI_MODEL : chatAIModelInput->text();
        embeddingAIUrl = embeddingAIUrlInput->text().isEmpty() ? DEFAULT_EMBEDDING_AI_URL : embeddingAIUrlInput->text();
        embeddingAIKey = embeddingAIKeyInput->text().isEmpty() ? DEFAULT_EMBEDDING_AI_KEY : embeddingAIKeyInput->text();
        embeddingAIModel = embeddingAIModelInput->text().isEmpty() ? DEFAULT_EMBEDDING_AI_MODEL : embeddingAIModelInput->text();

        useBuiltinChatAI = useBuiltinChatAICheckBox->isChecked();
        useBuiltinEmbeddingAI = useBuiltinEmbeddingAICheckBox->isChecked();

        chatAIModelPath = chatAIModelPathInput->text().isEmpty() ? QCoreApplication::applicationDirPath() + DEFAULT_CHAT_AI_MODEL_PATH : chatAIModelPathInput->text();
        chatAIHost = chatAIHostInput->text().isEmpty() ? DEFAULT_CHAT_AI_HOST : chatAIHostInput->text();
        chatAIPort = chatAIPortInput->text().isEmpty() ? DEFAULT_CHAT_AI_PORT : chatAIPortInput->text();
        chatAITemp = chatAITempInput->text().isEmpty() ? DEFAULT_CHAT_AI_TEMP : chatAITempInput->text();
        chatAIContextSize = chatAIContextSizeInput->text().isEmpty() ? DEFAULT_CHAT_AI_CONTEXT_SIZE : chatAIContextSizeInput->text();
        chatAINgl = chatAINglInput->text().isEmpty() ? DEFAULT_CHAT_AI_NGL : chatAINglInput->text();

        embeddingAIModelPath = embeddingAIModelPathInput->text().isEmpty() ? QCoreApplication::applicationDirPath() + DEFAULT_EMBEDDING_AI_MODEL_PATH : embeddingAIModelPathInput->text();
        embeddingAIHost = embeddingAIHostInput->text().isEmpty() ? DEFAULT_EMBEDDING_AI_HOST : embeddingAIHostInput->text();
        embeddingAIPort = embeddingAIPortInput->text().isEmpty() ? DEFAULT_EMBEDDING_AI_PORT : embeddingAIPortInput->text();
        embeddingAITemp = embeddingAITempInput->text().isEmpty() ? DEFAULT_EMBEDDING_AI_TEMP : embeddingAITempInput->text();
        embeddingAIContextSize = embeddingAIContextSizeInput->text().isEmpty() ? DEFAULT_EMBEDDING_AI_CONTEXT_SIZE : embeddingAIContextSizeInput->text();
        embeddingAINgl = embeddingAINglInput->text().isEmpty() ? DEFAULT_EMBEDDING_AI_NGL : embeddingAINglInput->text();

        saveSettings();
        qDebug() << "AI服务设置已更新";
    }
}

bool AIServiceSettings::performUrlTest(const QString &url, const QString &apiKey, const QString &model, bool isChat, QString *resultMessage)
{
    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    request.setRawHeader("Authorization", QString("Bearer %1").arg(apiKey).toUtf8());

    QJsonObject payload;
    if (isChat) {
        payload["model"] = model;
        QJsonArray messages;
        QJsonObject message;
        message["role"] = "user";
        message["content"] = "Hello";
        messages.append(message);
        payload["messages"] = messages;
    } else {
        payload["model"] = model;
        payload["input"] = "Hello";
        payload["encoding_format"] = "float";
    }

    QNetworkReply *reply = networkManager->post(request, QJsonDocument(payload).toJson());

    QEventLoop loop;
    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();

    if (reply->error() == QNetworkReply::NoError) {
        QByteArray responseData = reply->readAll();
        QJsonDocument jsonResponse = QJsonDocument::fromJson(responseData);
        QJsonObject jsonObject = jsonResponse.object();

        if (isChat) {
            if (jsonObject.contains("choices") && jsonObject["choices"].isArray()) {
                *resultMessage = "Chat AI URL 测试成功";
                reply->deleteLater();
                return true;
            } else {
                *resultMessage = "Chat AI URL 测试失败: 响应格式不正确";
                reply->deleteLater();
                return false;
            }
        } else {
            if (jsonObject.contains("data") && jsonObject["data"].isArray()) {
                QJsonArray dataArray = jsonObject["data"].toArray();
                if (!dataArray.isEmpty() && dataArray[0].isObject()) {
                    QJsonObject embeddingObject = dataArray[0].toObject();
                    if (embeddingObject.contains("embedding") && embeddingObject["embedding"].isArray()) {
                        *resultMessage = "Embedding AI URL 测试成功";
                        reply->deleteLater();
                        return true;
                    }
                }
            }
            *resultMessage = "Embedding AI URL 测试失败: 响应格式不正确";
            reply->deleteLater();
            return false;
        }
    } else {
        *resultMessage = isChat ? 
            QString("Chat AI URL 测试失败: %1").arg(reply->errorString()) :
            QString("Embedding AI URL 测试失败: %1").arg(reply->errorString());
        reply->deleteLater();
        return false;
    }
}

